import fs from 'fs'
import path from 'path'
import { errorLog } from './logs'
import decomment from 'decomment'

/**
 * 格式化文件名
 * @param {string | undefined} targetDir
 */
export const formatTargetDir = function (targetDir: string) {
  return targetDir?.trim().replace(/\/+$/g, '')
}

/**
 * 文件是否为空文件
 * @param {string} path
 */
export const isEmpty = function (path: string) {
  if (!fs.existsSync(path)) return true
  const files = fs.readdirSync(path)
  return files.length === 0 || (files.length === 1 && files[0] === '.git')
}

/**
 * 清空文件
 * @param {string} dir
 */
export const emptyDir = function (dir: string) {
  if (!fs.existsSync(dir)) {
    return
  }
  for (const file of fs.readdirSync(dir)) {
    fs.rmSync(path.resolve(dir, file), { recursive: true, force: true })
  }
}

/**
 * 文件是否存在
 * @param {string} 文件路径
 */
export const isExist = function (targetPath: string) {
  const targetDir = path.dirname(targetPath)
  return fs.existsSync(targetDir) && fs.existsSync(targetPath)
}

/**
 * 删除文件
 * @param {string} 文件路径
 * @returns
 */
export const delFile = function (targetPath: string) {
  if (!fs.existsSync(targetPath)) return
  fs.rmSync(targetPath, { recursive: true, force: true })
}

/**
 * 获取配置文件并删除jsonc中的注释
 * @param {string} 文件路径
 * @returns
 */
const cutAnnotation = function (targetPath: string) {
  try {
    const str = decomment(fs.readFileSync(targetPath, 'utf-8'))
    return JSON.parse(str)
  } catch (error) {
    errorLog('配置文件解析失败，请执行 `zoro i` 重新生成配置信息')
    process.exit()
  }
}

export interface CONFIG {
  name: string
  script: string
  host: string
  port: number
  username?: string
  password?: string
  distPath: string
  webDir: string
  command: string
  privateKeyPath: string
  passphrase: string
  projectName: string
}
// 检查zoro配置是否合理
export const checkDeployConfig = function (targetPath: string) {
  if (!fs.existsSync(targetPath)) {
    console.log(`缺少部署相关的配置，请运行${('zoro init')}下载部署配置`)
    process.exit()
  }

  // 获取执行zoro的项目名称
  let projectName = ''
  if (isExist(path.join(process.cwd(), 'package.json'))) {
    projectName = JSON.parse(
      fs.readFileSync(path.join(process.cwd(), 'package.json'), 'utf-8')
    ).name
  }
  const config = cutAnnotation(targetPath)
  const { privateKeyPath, passphrase } = config
  const keys = Object.keys(config)
  const configs: CONFIG[] = []
  for (const key of keys) {
    if (config[key] instanceof Object) {
      config[key].command = key
      privateKeyPath && (config[key].privateKeyPath = privateKeyPath)
      passphrase && (config[key].passphrase = passphrase)
      config[key].projectName = projectName
      configs.push(config[key])
    }
  }
  return configs
}

type SCHEMA = Omit<CONFIG, 'command'|'privateKeyPath'|'passphrase'|'projectName'>

const DEPLOY_SCHEMA = {
  name: '',
  script: '',
  host: '',
  port: 22,
  username: '',
  password: '',
  distPath: '',
  webDir: ''
}

const PRIVATE_KEY_DEPLOY_SCHEMA = {
  name: '',
  script: '',
  host: '',
  port: 22,
  distPath: '',
  webDir: ''
}

// 检查配置是否符合特定schema
export const checkConfigScheme = function (config: CONFIG) {
  const deploySchemaKeys:Array<string> = config.privateKeyPath ? Object.keys(PRIVATE_KEY_DEPLOY_SCHEMA) : Object.keys(DEPLOY_SCHEMA)
  const configKeys = Object.keys(config)

  const neededKeys = []
  const unConfigedKeys = []

  for (const key of deploySchemaKeys) {
    if (!configKeys.includes(key)) {
      neededKeys.push(key)
    }
    const vl = config[key as keyof SCHEMA]
    if (vl === '' || vl === null || vl === undefined) {
      unConfigedKeys.push(key)
    }
  }
  let flag = false
  if (neededKeys.length > 0) {
    errorLog(`${config.command}缺少${neededKeys.join(',')}配置，请检查配置`)
    flag = true
  }
  if (unConfigedKeys.length > 0) {
    errorLog(`${config.command}中的${unConfigedKeys.join(', ')}暂未配置，请设置该配置项`)
    flag = true
  }
  if (flag) { process.exit() }
}
